package com.saurshaz.test.roo.trading.controllers;

import java.util.Map;
import java.util.Queue;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.saurshaz.test.roo.trading.SecurityTrade;
import com.saurshaz.test.roo.trading.bo.FinancialInstrument;
import com.saurshaz.test.roo.trading.controllers.backingforms.SecurityTradeForm;
import com.saurshaz.test.roo.trading.services.SecurityTradingService;
import com.saurshaz.test.roo.trading.services.SecurityTypeService;
import com.saurshaz.test.roo.trading.services.TradeTypeService;

@RequestMapping("/securitytrade/**")
@Controller
public class SecurityTradeController {

	@Qualifier("securityTradeService")
	@Autowired(required = true)
	private SecurityTradingService securityTradeService;

	@Qualifier("tradeTypeService")
	@Autowired(required = true)
	private TradeTypeService tradeTypeService;

	@Qualifier("securityTypeService")
	@Autowired(required = true)
	private SecurityTypeService securityTypeService;

	public TradeTypeService getTradeTypeService() {
		return tradeTypeService;
	}

	public void setTradeTypeService(TradeTypeService tradeTypeService) {
		this.tradeTypeService = tradeTypeService;
	}

	public SecurityTypeService getSecurityTypeService() {
		return securityTypeService;
	}

	public void setSecurityTypeService(SecurityTypeService securityTypeService) {
		this.securityTypeService = securityTypeService;
	}

	public SecurityTradingService getSecurityTradeService() {
		return securityTradeService;
	}

	public void setSecurityTradeService(
			SecurityTradingService securityTradeService) {
		this.securityTradeService = securityTradeService;
	}

	@RequestMapping
	public void get(ModelMap modelMap, HttpServletRequest request,
			HttpServletResponse response) {
	}

	@RequestMapping(method = RequestMethod.POST, value = "{id}")
	public void post(@PathVariable Long id, ModelMap modelMap,
			HttpServletRequest request, HttpServletResponse response) {
	}

	@RequestMapping
	public String index() {
		return "securitytrade/index";
	}

	@RequestMapping(value = "list")
	public String list(Model uiModel, HttpSession httpSession) {
		uiModel.addAttribute("listSecurities", getSecurityTradeService()
				.getAllSecurities());

		Map<String, Queue<FinancialInstrument>> mapOfQueues = (Map<String, Queue<FinancialInstrument>>) httpSession
				.getAttribute("securitiesMap");

		String strAttr = (String) httpSession.getAttribute("showStatus");
		boolean showPnL = false;
		if (StringUtils.hasText(strAttr)) {
			showPnL = (Boolean) httpSession.getAttribute("showStatus");
		}

		if (showPnL && CollectionUtils.isEmpty(mapOfQueues)) {
			// Initialise the map from DB values
			mapOfQueues = securityTradeService.getSecuritiesCollection();

			// update to session level attribute
			httpSession.setAttribute("securitiesMap", mapOfQueues);
		}

		return "securitytrade/list";
	}

	@RequestMapping(method = RequestMethod.GET, value = "create")
	public String create(@ModelAttribute SecurityTradeForm securityTradeForm,
			Model uiModel) {
		// Prepare backing object
		uiModel.addAttribute("command", new SecurityTradeForm());

		uiModel.addAttribute("listSecurities", getSecurityTradeService()
				.getAllSecurities());
		uiModel.addAttribute("listTradeTypes", getTradeTypeService()
				.getAllTradeTypes());
		uiModel.addAttribute("listSecurityTypes", getSecurityTypeService()
				.getAllSecurityTypes());

		return "securitytrade/create";
	}

	@RequestMapping(value = "save")
	public String save(
			@Valid @ModelAttribute SecurityTradeForm securityTradeForm,
			BindingResult bindingResult, HttpSession httpSesion, Model uiModel) {
		if (bindingResult.hasErrors()) {
			return save(securityTradeForm, bindingResult, httpSesion, uiModel);
		}

		SecurityTrade securityTrade = securityTradeService
				.createSecurity(securityTradeForm);

		// update the queoue for f.i. objects for pnl calculation
		Map<String, Queue<FinancialInstrument>> mapOfQueues = (Map<String, Queue<FinancialInstrument>>) httpSesion
				.getAttribute("securitiesMap");

		if (CollectionUtils.isEmpty(mapOfQueues)) {
			// Initialise the map from DB values
			mapOfQueues = securityTradeService.getSecuritiesCollection();

			// update to session level attribute
			httpSesion.setAttribute("securitiesMap", mapOfQueues);
		}

		securityTradeService.updateSecuritiesCollection(securityTrade,
				mapOfQueues);

		// get data from request and save as entity, return to listing page

		return list(uiModel, httpSesion);
	}

	@RequestMapping(value = "get_market_value.json")
	public @ResponseBody
	String getMarketValue(@RequestParam("0") String quantity,
			@RequestParam("1") String price,
			@RequestParam("2") String tradeTypeId) {
		return securityTradeService
				.getMarketValue(quantity, price, tradeTypeId);
	}

	@RequestMapping(value = "show_pnl.json")
	public @ResponseBody
	Boolean showPnL(@RequestParam("status") String status, HttpSession session) {

		Boolean showStatus = false;
		if (StringUtils.hasText(status)) {
			showStatus = Boolean.parseBoolean(status);
		}
		session.setAttribute("showStatus", showStatus);
		return showStatus;
	}

}
